package com.lfp.config.rabbitmq;

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * @Description TTL 队列配置类
 *
 *  队列关系参考./images下：
 *      延时-死信队列.png
 *      动态-延时-死信队列.png
 *
 * @Author lfp
 * @Date 2022/7/17
 * @Version 1.0
 */
@Configuration
public class TtlQueueConfig {
    //todo 1、给所有交换机、队列命名
    //普通交换机名称
    public static final String X_EXCHANGE = "X";
    //死信交换机名称
    public static final String Y_DEAD_LEFTTER_EXCHANGE = "Y";

    //普通队列名称
    public static final String QUEUE_A = "QA";
    public static final String QUEUE_B = "QB";

    public static final String QUEUE_C = "QC";//新添加普通队列名称
    //死信队列名称
    public static final String DEAD_LEFTTER_QUEUE_D = "QD";

    //路由键
    public static final String ROUTING_KEY_XEXCHANGE_TO_QUEUEA = "XA";
    public static final String ROUTING_KEY_XEXCHANGE_TO_QUEUEB = "XB";
    public static final String ROUTING_KEY_XEXCHANGE_TO_QUEUEC = "XC";

    public static final String ROUTING_KEY_YEXCHANGE_TO_DEAD_LEFTTER_QUEUD = "YD";


    //todo 2、交换机配置
    //声明普通交换机 xExchange
    @Bean("xExchange")
    public DirectExchange xExchange(){
        return new DirectExchange(X_EXCHANGE);
    }
    //声明死信交换机 yExchange
    @Bean("yExchange")
    public DirectExchange yExchange(){
        return new DirectExchange(Y_DEAD_LEFTTER_EXCHANGE);
    }


    //todo 3、队列配置
    //声明普通队列 TTL为10S
    @Bean("queueA")
    public Queue queueA(){
        //return new Queue(QUEUE_A);

        Map<String,Object> arguments = new HashMap<>(3);
        //设置死信交换机
        arguments.put("x-dead-letter-exchange",Y_DEAD_LEFTTER_EXCHANGE);
        //设置死信RoutingKey
        arguments.put("x-dead-letter-routing-key",
                ROUTING_KEY_YEXCHANGE_TO_DEAD_LEFTTER_QUEUD);
        //设置TTL（存活时间/过期时间） 单位是ms
        arguments.put("x-message-ttl",10000);

        return QueueBuilder.durable(QUEUE_A)
                .withArguments(arguments)
                .build();
    }

    //声明普通队列 TTL为40S
    @Bean("queueB")
    public Queue queueB(){
        //return new Queue(QUEUE_A);

        Map<String,Object> arguments = new HashMap<>(3);
        //设置死信交换机
        arguments.put("x-dead-letter-exchange",Y_DEAD_LEFTTER_EXCHANGE);
        //设置死信RoutingKey
        arguments.put("x-dead-letter-routing-key",
                ROUTING_KEY_YEXCHANGE_TO_DEAD_LEFTTER_QUEUD);
        //设置TTL（存活时间/过期时间） 单位是ms
        arguments.put("x-message-ttl",40000);

        return QueueBuilder.durable(QUEUE_B)
                .withArguments(arguments)
                .build();
    }

    @Bean("queueC")
    public Queue queueC(){
        Map<String,Object> arguments = new HashMap<>(3);
        //设置死信交换机
        arguments.put("x-dead-letter-exchange",Y_DEAD_LEFTTER_EXCHANGE);
        //设置死信RoutingKey
        arguments.put("x-dead-letter-routing-key",
                ROUTING_KEY_YEXCHANGE_TO_DEAD_LEFTTER_QUEUD);
        //这里不再设置过期时间
        //arguments.put("x-message-ttl",40000);

        return QueueBuilder.durable(QUEUE_C)
                .withArguments(arguments)
                .build();
    }

    //死信队列 无参数
    @Bean("queueD")
    public Queue queueD(){
        return QueueBuilder
                .durable(DEAD_LEFTTER_QUEUE_D)
                .build();
    }


    //todo 3、将队列绑定到目标交换机
    //绑定
    //将队列A绑定到交换机X
    //将队列绑定到交换机 队列和交换机从容器中获取
    @Bean
    public Binding queueABindToExchangeX(@Qualifier("queueA") Queue queueA,
                                         @Qualifier("xExchange") DirectExchange xExchange){
        return BindingBuilder.
                bind(queueA) //绑定指的 定队列
                .to(xExchange)//到指定的 交换机
                .with(ROUTING_KEY_XEXCHANGE_TO_QUEUEA);//指定路由键
    }

    //将队列B绑定到交换机X
    @Bean
    public Binding queueBBindToExchangeX(@Qualifier("queueB") Queue queueB,
                                         @Qualifier("xExchange") DirectExchange xExchange){
        return BindingBuilder.
                bind(queueB) //绑定指的 定队列
                .to(xExchange)//到指定的 交换机
                .with(ROUTING_KEY_XEXCHANGE_TO_QUEUEB);//指定路由键
    }

    //将队列C绑定到交换机X
    @Bean
    public Binding queueCBindToExchangeX(@Qualifier("queueC") Queue queueC,
                                         @Qualifier("xExchange") DirectExchange xExchange){
        return BindingBuilder.
                bind(queueC) //绑定指的 定队列
                .to(xExchange)//到指定的 交换机
                .with(ROUTING_KEY_XEXCHANGE_TO_QUEUEC);//指定路由键
    }

    //将死信队列D 绑定到死信交换机Y
    @Bean
    public Binding queueDBindToExchangeY(@Qualifier("queueD") Queue queueD,
                                         @Qualifier("yExchange") DirectExchange yExchange){
        return BindingBuilder.
                bind(queueD) //绑定指的 定队列
                .to(yExchange)//到指定的 交换机
                .with(ROUTING_KEY_YEXCHANGE_TO_DEAD_LEFTTER_QUEUD);//指定路由键
    }

}
